/**
 * File Name	: DateTime.cpp
 * Location		: /Core/
 * Lib.Name		: Core.a
 * Mod. 1 by	: AS (25-09-06)
 */

#include "stdafx.h"
#include "DateTime.h"

namespace Core
{
	void GetStructTM(struct tm& p_TM, unsigned long p_Time)
	{
		const time_t t_Time = (time_t)p_Time;
#ifdef VC
		localtime_s(&p_TM, &t_Time);
#else
		p_TM = *localtime(&t_Time);
#endif
	}

	DateTime::DateTime()
	{
		m_Seconds = (unsigned long) time(0);
	}

	DateTime::DateTime(unsigned long p_Seconds)
	{
		m_Seconds = p_Seconds;
	}

	DateTime::DateTime(unsigned short p_Year, unsigned char p_Month, unsigned char p_Date,
			unsigned char p_Hour, unsigned char p_Minute, unsigned char p_Second)
	{
		struct tm t_Local;
		GetStructTM(t_Local, (unsigned long) time(0));
        if (p_Year >= 1900)
            t_Local.tm_year = p_Year - 1900;
        if (p_Month < 12)
            t_Local.tm_mon = p_Month;
        if ((p_Date > 0) && (p_Date <= 31))
            t_Local.tm_mday = p_Date;
        if (p_Hour < 24)
            t_Local.tm_hour = p_Hour;
        if (p_Minute < 60)
            t_Local.tm_min = p_Minute;
        if (p_Second < 60)
            t_Local.tm_sec = p_Second;
        if (mktime(&t_Local) == -1) // error
            exit(1);
	}

	long DateTime::Delta(DateTime p_DateTime)
	{
		return (m_Seconds - p_DateTime.GetTotalSeconds());
	}

	unsigned short DateTime::GetYear()
	{
		struct tm t_Local;
		GetStructTM(t_Local, m_Seconds);
		return (unsigned short) (t_Local.tm_year+1900);
	}

	unsigned char DateTime::GetMonth()
	{
		struct tm t_Local;
		GetStructTM(t_Local, m_Seconds);
		return (unsigned char) t_Local.tm_mon;
	}

	unsigned char DateTime::GetDate()
	{
		struct tm t_Local;
		GetStructTM(t_Local, m_Seconds);
		return (unsigned char) t_Local.tm_mday;
	}

	unsigned char DateTime::GetDay()
	{
		struct tm t_Local;
		GetStructTM(t_Local, m_Seconds);
		return (unsigned char) t_Local.tm_wday;
	}

	unsigned char DateTime::GetHour()
	{
		struct tm t_Local;
		GetStructTM(t_Local, m_Seconds);
		return (unsigned char) t_Local.tm_hour;
	}

	unsigned char DateTime::GetMinute()
	{
		struct tm t_Local;
		GetStructTM(t_Local, m_Seconds);
		return (unsigned char) t_Local.tm_min;
	}

	unsigned char DateTime::GetSecond()
	{
		struct tm t_Local;
		GetStructTM(t_Local, m_Seconds);
		return (unsigned char) t_Local.tm_sec;
	}

	unsigned long DateTime::GetTotalSeconds()
	{
		return m_Seconds;
	}

	void DateTime::SetYear(unsigned short p_Year)
	{
		struct tm t_Local;
		GetStructTM(t_Local, m_Seconds);
		t_Local.tm_year = (int)(p_Year-1900);
		m_Seconds = (unsigned long) mktime(&t_Local);
	}

	void DateTime::SetMonth(unsigned char p_Month)
	{
		struct tm t_Local;
		GetStructTM(t_Local, m_Seconds);
		t_Local.tm_mon = (int)(p_Month);
		m_Seconds = (unsigned long) mktime(&t_Local);
	}

	void DateTime::SetDate(unsigned char p_Date)
	{
		struct tm t_Local;
		GetStructTM(t_Local, m_Seconds);
		t_Local.tm_mday = (int)(p_Date);
		m_Seconds = (unsigned long) mktime(&t_Local);
	}

	void DateTime::SetHour(unsigned char p_Hour)
	{
		struct tm t_Local;
		GetStructTM(t_Local, m_Seconds);
		t_Local.tm_hour = (int)(p_Hour);
		m_Seconds = (unsigned long) mktime(&t_Local);
	}

	void DateTime::SetMinute(unsigned char p_Minute)
	{
		struct tm t_Local;
		GetStructTM(t_Local, m_Seconds);
		t_Local.tm_min = (int)(p_Minute);
		m_Seconds = (unsigned long) mktime(&t_Local);
	}

	void DateTime::SetSecond(unsigned char p_Second)
	{
		struct tm t_Local;
		GetStructTM(t_Local, m_Seconds);
		t_Local.tm_sec = (int)(p_Second);
		m_Seconds = (unsigned long) mktime(&t_Local);
	}

	bool DateTime::operator==(DateTime& p_DateTime)
	{
		return (m_Seconds == p_DateTime.GetTotalSeconds());
	}

	bool DateTime::operator>(DateTime& p_DateTime)
	{
		return (m_Seconds > p_DateTime.GetTotalSeconds());
	}

	bool DateTime::operator>=(DateTime& p_DateTime)
	{
		return (m_Seconds >= p_DateTime.GetTotalSeconds());
	}

	bool DateTime::operator<(DateTime& p_DateTime)
	{
		return (m_Seconds < p_DateTime.GetTotalSeconds());
	}

	bool DateTime::operator<=(DateTime& p_DateTime)
	{
		return (m_Seconds <= p_DateTime.GetTotalSeconds());
	}

	std::string DateTime::ToString(std::string p_Format)
	{
		struct tm t_Local;
		GetStructTM(t_Local, m_Seconds);
		std::string ret;
		char str_result[1000];
		strftime(str_result, 1000, p_Format.c_str(), &t_Local);
		ret = str_result;
		return ret;
	}

	std::ostream& operator<<(std::ostream& p_Out, DateTime& p_DateTime)
	{
		p_Out << p_DateTime.ToString("%A, %d %B %Y, %H:%M:%S");
		return p_Out;
	}
}
